#! /usr/bin/python3
# -*- Coding: utf-8 -*-

'''
pyGuessGame 1.2.0-pre2

LICENSE: GPLv3.0

changelog: 


'''

import datetime
import os
import random as r
import time
from math import *
import sys
import error as err
import info as i
import warn as w

import colorama as c

defaultNumber = 1000

enabledTesting = False



def argParser():
    pass
    arg = sys.argv
    del arg[0]
    for i in range(0, len(arg)):
        arg[i] = arg[i].lower()
    for i in arg:
        if i == '-enable-testing' or i == '--enable-testing':
            global enabledTesting
            enabledTesting = True
        else:
            err.err("argParser", f"{i} options not defined")
    

def readScore():
    '''
    arg: None
    return:
    (minTime1: str 最小次数, minTime2: str 最小时间): arr or
    False if open file error
    '''
    try:
        f = open("maxScore.txt", "r", encoding="utf-8")
        s = f.read().replace("\r", "").replace("\n", "").split(" ")
        if (len(s) != 2):
            raise ValueError("maxScore.txt invalid")
        return s
    except:
        print(f"[{c.Fore.RED}ERROR{c.Fore.RESET}] {c.Fore.RED}{c.Back.WHITE} score reader: {c.Back.RESET}File not found or invalid{c.Fore.RESET}{c.Back.RESET}")

        return False


def saveScore(minTime1, minTime2):
    # minTime1: 次数，minTime2: 时间
    pass


def getIsRead():
    try:
        f = open("read.txt")
        s = f.read()
        f.close()
        return True
    except:
        return False

def genSettings():
    '''
    genSettings
    作用：创建设置文件
    '''
    settingsPath = "settings.txt"
    try:
        a = i.ins("settings creator: type default number(100~10000000)")
        a = int(a)
        if (a < 100 or a > 100000000):
            raise ValueError("Value out of range")
    except Exception as e:
        err.fatal("settings creator", "EOF or not a number or number out of range")

        raise ValueError()
    else:
        f = open(settingsPath, "w+", encoding="utf-8")
        f.write(str(a))
        f.close()
        return a


def readSettings():
    '''
    readSettings
    作用：读取设置文件

    '''
    i.time("initialize progress", "Trying open and read settings file...")
    try:
        f = open("settings.txt", "r", encoding="utf-8")
        return int(f.read().replace("\r", "").replace("\n", ""))
    except FileNotFoundError:
        err.err("settings reader", "File not found")
        return False
    except ValueError:
        err.err("settings reader", "File invalid")
        return False


def main(ver):
    # Check program and call main
    i.ok("pyGuessGame", "pyGuessGame version 1.2.0-pre1 started successful")    
    i.time("main", "parsing arguments...")
    argParser()
    i.ok("main", "arguments parsed successful")
    w.warn("main",  "-enable-testing defined in arguments. There may be unexpected crashes and some inexplicable errors") \
    if enabledTesting == True else \
    i.info("main", "highest score save&read function was added in 1.1.0," + 
    " but still testing. Enable it run this program with \"-enable-testing\" argument.")
    if (getIsRead() == False):
        i.ins("sorry: score save&read function won't add in 1.2.0, 1.2.0 will fix a few bugs and then release. Press enter to resume")
        f = open("read.txt", "w+")
        f.write("1")
        f.close()
    else:
        pass
    
    i.info("pyGuessGame", f"the bug of auto-guess was {c.Fore.RED}FIXED in 1.1.0{c.Fore.GREEN}! ")
    i.time("pyGuessGame", "Start initialize!")
    t = readSettings()
    if (t == False):
        defaultNumber = genSettings()
    

    else:
        defaultNumber = t
    i.info("debug", f"{defaultNumber=}")
    i.ok("initialize progress", "Initialize progress initialized successfully")
    i.time("pyGuessGame", "Starting console...")
    console(defaultNumber)


def guess(num):
    # random number
    n = r.randint(0, num)
    print(f"[ {c.Fore.GREEN}OK{c.Fore.RESET} ] {c.Fore.RED}guess progress{c.Fore.RESET}: {c.Fore.GREEN}Number randomed! {c.Fore.RESET}")
    print("Guess the number, type -1 to exit")
    start = time.time()
    t = 0
    print(f"Max number: {num}")
    while (True):
        try:
            a = int(input(f"?> {c.Fore.GREEN}"))
            print(f"{c.Fore.RESET}", end="")
            if (a == ''):
                continue
            if (a == -1):
                print(f"corrert number: {n}")
                break
            elif (a > n):
                print(f"{c.Fore.RED}too big{c.Fore.RESET}")
                t += 1
            elif (a < n):
                print(f"{c.Fore.YELLOW}too small{c.Fore.RESET}")
                t += 1
            else:
                end = time.time()
                print(f"{c.Fore.GREEN}Right{c.Fore.RESET}")
                print(
                    f"You Win! Used Time {end - start} seconds and guess {t} time(s).")
                break
        except ValueError:
            print(
                f"{c.Fore.RESET}[{c.Fore.RED}ERROR{c.Fore.RESET}] {c.Fore.RED}{c.Back.WHITE}auto guess: {c.Back.RESET}Invalid integer{c.Fore.RESET}{c.Back.RESET}")
        except KeyboardInterrupt:
            print(
                f"\n{c.Fore.RESET}[{c.Fore.RED}ERROR{c.Fore.RESET}] {c.Fore.RED}{c.Back.WHITE}auto guess: {c.Back.RESET}User interrupt{c.Fore.RESET}{c.Back.RESET}")
            break
        except:
            print(c.Fore.RESET, end='')
            continue


def autoGuess(num):
    # random number
    # while computer guess number
    n = r.randint(0, num)
    print(f"[ {c.Fore.GREEN}OK{c.Fore.RESET} ] {c.Fore.RED}auto-guess progress{c.Fore.RESET}: {c.Fore.GREEN}Number randomed! {c.Fore.RESET}")
    print("Auto-Guessing the number, press Ctrl-C to exit")
    start = time.time()
    t = 0
    maxNum = num
    minNum = 0

    while (True):
        try:
            a = abs(maxNum - minNum) // 2 + minNum
            print(f"guess: {a}")
            time.sleep(.75)
            print(f"{c.Fore.RESET}", end="")
            if (a > n):
                print(f"{c.Fore.RED}too big{c.Fore.RESET}\n")
                maxNum = a
                t += 1
            elif (a < n):
                print(f"{c.Fore.YELLOW}too small{c.Fore.RESET}\n")
                minNum = 0 + a
                t += 1
            else:
                end = time.time()
                print(f"{c.Fore.GREEN}Right{c.Fore.RESET}\n")
                print(f"Auto-guess Win! Guessed {t} time(s).")
                break
        except KeyboardInterrupt:
            print(
                f"\n{c.Fore.RESET}[{c.Fore.RED}ERROR{c.Fore.RESET}] {c.Fore.RED}{c.Back.WHITE}auto guess: {c.Back.RESET}User interrupt{c.Fore.RESET}{c.Back.RESET}")
            break
        except:
            print(c.Fore.RESET, end='')
            continue


def console(num):
    i.ok("console module", "console module started successfully")
    print("New command ADDED! TEST THEM WITH \"-enable-testing\"") if enabledTesting == False else print('', end = '')
    print(f"""Type \"help\" show tips, Type \"exit\" exit.""", end='\n')
    while True:
        cmd = input(f">>> {c.Fore.CYAN}").lower().strip()
        print(f"{c.Fore.RESET}", end="")
        if (cmd == 'help'):
            print(f"pyGuessGame Usage: \n" +
                  f"{c.Fore.GREEN}help show this message,\n{c.Fore.YELLOW}start to start a new game," +
                  f"\n{c.Fore.BLUE}auto to start an auto-guess game {c.Fore.RED}(BUGS WAS FIXED IN 1.1.0){c.Fore.RESET},\n{c.Fore.MAGENTA}exit to exit game.{c.Fore.RESET}")
        elif (cmd == 'exit'):
            print(f"{c.Fore.GREEN}Bye!{c.Fore.RESET}")
            break
        elif (cmd == 'start'):
            guess(num)
        elif cmd == "auto":
            autoGuess(num)
        elif cmd == '':
            continue
        else:
            print(f"{c.Fore.RED}bad command{c.Fore.RESET}")


if __name__ == '__main__':
    # Start main (version)
    try:
        main("1.1.0")
    # 以下为伪-守护进程
    except KeyboardInterrupt as e:
        err.fatal("daemon thread", "program crashed because user interrupted")

    except EOFError:
        print(
            f"\n{c.Fore.RESET}[{c.Fore.RED}FATAL{c.Fore.RESET}] {c.Fore.RED}{c.Back.WHITE}daemon thread: {c.Back.RESET}Program crashed: {e}{c.Fore.RESET}{c.Back.RESET}")
        err.fatal("daemon thread", "program crashed because unexpected EOF")    

    except Exception as e:
        err.fatal("daemon thread", f"program crashed because some except errors")    

